package com.eds.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eds.dto.CourseImageMessage;
import com.eds.log.LogUtil;
import com.eds.mapper.CourseMapper;
import com.eds.mapper.OssImageMapper;
import com.pojo.Course;
import com.pojo.OssImage;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

@Component
@Slf4j
public class CourseImageConsumer {

    // 记录消息处理失败次数的阈值，超过这个次数不再重试
    private static final int MAX_RETRY_COUNT = 3;
    @Autowired
    private OssImageMapper ossImageMapper;
    @Autowired
    private CourseMapper courseMapper;

    @RabbitListener(queues = "course.image.queue")
    public void processImage(CourseImageMessage message, Channel channel, Message amqpMessage) {
        long deliveryTag = amqpMessage.getMessageProperties().getDeliveryTag();
        // 从消息头获取重试次数，如果没有则默认为0
        int retryCount = (int) amqpMessage.getMessageProperties().getHeaders().getOrDefault("x-retry-count", 0);
        try {
            LogUtil.info(CourseImageConsumer.class, "处理课程图片: courseId={" +
                    message.getCourseId() + " }relationType={" + message.getRelationType(), "}重试次数={" + retryCount + "}");
            // 检查该消息是否已经处理过（查询是否已存在相同URL和课程ID的记录）
            QueryWrapper<OssImage> ossImageQuery = new QueryWrapper<>();
            ossImageQuery.eq("url", message.getImageUrl())
                    .eq("course_id", message.getCourseId())
                    .eq("relation_type", message.getRelationType());
            int existingCount = ossImageMapper.selectCount(ossImageQuery);

            if (existingCount > 0) {
                LogUtil.info(CourseImageConsumer.class, "该图片记录已存在，不再重复处理: {", message.getImageUrl() + "}");
                // 确认消息，不再处理
                channel.basicAck(deliveryTag, false);
                return;
            }

            // 1. 保存图片信息到OSS表
            OssImage ossImage = new OssImage();
            ossImage.setUrl(message.getImageUrl());
            ossImage.setRelationType(message.getRelationType());
            ossImage.setUserId(message.getUserId());
            ossImage.setCourseId(message.getCourseId());
            ossImage.setDescription(getImgDescription(message.getRelationType(), message.getImageIndex()));
            ossImage.setUploadTime(new Date());
            try {
                int ossInsert = ossImageMapper.insert(ossImage);
                LogUtil.info(CourseImageConsumer.class, "新增课程内容图片" + message.getCourseId() + "的地址为：{" + message.getImageUrl() + "}");
                if (ossInsert > 0) {
                    // 2. 更新课程表中对应的图片字段
                    boolean updateSuccess = false;
                    if ("title".equals(message.getRelationType())) {
                        //处理标题图片
                        updateSuccess = updateTitleImage(message.getCourseId(), message.getImageUrl());
                        LogUtil.info(CourseImageConsumer.class, "更新课程标题：" + message.getCourseId() + "的地址为：{" + message.getImageUrl() + "}");
                    } else {
                        updateSuccess = updateCourseImage(message.getCourseId(), message.getImageIndex(), message.getImageUrl());
                        LogUtil.info(CourseImageConsumer.class, "更新课程内容：" + message.getImageIndex() + message.getCourseId() + "的地址为：{" + message.getImageUrl() + "}");

                    }
                    if (updateSuccess) {
                        //处理成功，确认消息
                        channel.basicAck(deliveryTag, false);
                        LogUtil.info(CourseImageConsumer.class, "课程图片处理完成: courseId={" + message.getCourseId() + "}, relationType={" + message.getRelationType() + "}");
                    } else {
                        //更新课程表失败，但Oss记录已插入
                        handleUpdateFailure(channel, deliveryTag, retryCount, message);
                    }
                } else {
                    // 处理失败，根据重试次数决定是否重新入队
                    handleInsertFailure(channel, deliveryTag, retryCount, message);
                }
            } catch (DuplicateKeyException e) {
                // 并发情况下可能发生的重复插入，视为成功
                LogUtil.warn(CourseImageConsumer.class, "图片记录已存在(并发冲突): {" + message.getImageUrl() + "}");
                channel.basicAck(deliveryTag, false);
            }

        } catch (Exception e) {
            LogUtil.error(CourseImageConsumer.class, "处理课程图片失败: " + e.getMessage(), e);
            try {
                // 根据重试次数决定是否重新入队
                if (retryCount >= MAX_RETRY_COUNT) {
                    // 超过最大重试次数，拒绝消息但不重新入队
                    LogUtil.warn(CourseImageConsumer.class, "消息处理失败超过{" + MAX_RETRY_COUNT + "}次，不再重试: {" + message + "}");
                    channel.basicReject(deliveryTag, false);
                } else {
                    // 增加重试次数并重新入队
                    amqpMessage.getMessageProperties().getHeaders().put("x-retry-count", retryCount + 1);
                    channel.basicNack(deliveryTag, false, true);
                }
            } catch (IOException ex) {
                LogUtil.error(CourseImageConsumer.class, "处理消息确认失败", ex);
            }
        }
    }

    /* *
     * 获取图片描述
     */
    private String getImgDescription(String relationType, int imageIndex) {
        if ("title".equals(relationType)) {
            return "课程标题图片";
        } else
            return "课程内容图片" + imageIndex;
    }


    /**
     * 更新课程标题图片
     */
    private boolean updateTitleImage(Long courseId, String imgUrl) {
        try {
            UpdateWrapper<Course> courseUpdateWrapper = new UpdateWrapper<>();
            courseUpdateWrapper.eq("course_id", courseId)
                    .set("title_img", imgUrl);
            int update = courseMapper.update(null, courseUpdateWrapper);
            return update > 0;
        } catch (Exception e) {
            LogUtil.error(CourseImageConsumer.class, "更新课程标题图片异常: " + e.getMessage(), e);
            return false;
        }
    }


    /**
     * 更新课程标题图片，使用直接SQL更新课程图片字段，避免反射和字段名不匹配问题
     */
    private boolean updateCourseImage(Long courseId, int index, String imgUrl) {
        try {
            // 确定要更新的字段名
            String columnName;
            switch (index) {
                case 1:
                    columnName = "content1_img"; // 确保这个字段名与数据库表一致
                    break;
                case 2:
                    columnName = "content2_img";
                    break;
                case 3:
                    columnName = "content3_img";
                    break;
                case 4:
                    columnName = "content4_img";
                    break;
                default:
                    LogUtil.error(CourseImageConsumer.class, "不支持的图片索引: {}", index);
                    return false;
            }

            // 使用UpdateWrapper更新
            UpdateWrapper<Course> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("course_id", courseId)
                    .set(columnName, imgUrl);

            // 执行更新并返回影响行数
            int rows = courseMapper.update(null, updateWrapper);

            if (rows <= 0) {
                LogUtil.error(CourseImageConsumer.class, "课程图片字段更新失败, courseId={" + courseId + "}, index={" + index + "}, columnName={" + columnName + "}");
                // 检查课程是否存在
                QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("course_id", courseId);
                Integer count = courseMapper.selectCount(queryWrapper);
                if (count <= 0) {
                    LogUtil.error(CourseImageConsumer.class, "课程不存在: {" + courseId + "}");
                }
                return false;
            }

            return true;
        } catch (Exception e) {
            LogUtil.error(CourseImageConsumer.class, "更新课程图片字段异常: " + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 处理插入OSS记录失败的情况
     */
    private void handleInsertFailure(Channel channel, long deliveryTag, int retryCount, CourseImageMessage message) throws IOException {
        if (retryCount >= MAX_RETRY_COUNT) {
            LogUtil.warn(CourseImageConsumer.class, "OSS记录插入失败超过{" + MAX_RETRY_COUNT + "}次，不再重试: {" + message + "}");
            channel.basicReject(deliveryTag, false);
            //logFailedMessage(message, new Exception("OSS记录插入失败"));
        } else {
            // 增加重试次数并重新入队
            LogUtil.warn(CourseImageConsumer.class, "OSS记录插入失败，重试次数: {" + (retryCount + 1) + "}");
            channel.basicNack(deliveryTag, false, true);
        }
    }

    /**
     * 处理更新课程表失败的情况
     */
    private void handleUpdateFailure(Channel channel, long deliveryTag, int retryCount, CourseImageMessage message) throws IOException {
        if (retryCount >= MAX_RETRY_COUNT) {
            LogUtil.warn(CourseImageConsumer.class, "OSS记录插入失败超过{" + MAX_RETRY_COUNT + "}次，不再重试: {" + message + "}");
            channel.basicReject(deliveryTag, false);
        } else {
            // 增加重试次数并重新入队
            LogUtil.warn(CourseImageConsumer.class, "课程表更新失败，重试次数: {}", retryCount + 1);
            channel.basicNack(deliveryTag, false, true);
        }
    }

    /**
     * 记录失败的消息
     */
    private void logFailedMessage(CourseImageMessage message, Exception e) {
        LogUtil.error(CourseImageConsumer.class, "消息处理最终失败，需人工处理: courseId={}, imageUrl={}, error={}",
                message.getCourseId(), message.getImageUrl(), e.getMessage());
    }
}